// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// o [author] rhyme_lph
// a [email]  rhymelph@gmail.com
// T [github] https://github.com/rhymelph

import 'dart:async';

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/custom_expense_data.dart';
import 'package:finance_app/src/entities/payslips_item_entity.dart';
import 'package:finance_app/src/http_service/http_payslips_service.dart';
import 'package:finance_app/src/mixin/format_group_map_mixin.dart';
import 'package:finance_app/src/mixin/search_data_list_mixin.dart';
import 'package:finance_app/src/provider/hr_payroll/views/employee_provider.dart';
import 'package:finance_app/src/provider/hr_payroll/views/payroll_provider.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/utils/permission_utils.dart';
import 'package:flutter/material.dart';

import '../hr_and_payroll_provider.dart';

class PayrollPaymentProvider extends BaseProvider<List<PayslipsItemEntity>>
    with SearchDataListMixin, FormatGroupMapLocalMixin<PayslipsItemEntity> {
  List<PayslipsItemEntity> currentSelectList = [];

  @override
  Future get dataFuture => HttpPayslipsService.payslipsList('unpaid');

  void onContinue() async {
    if (currentSelectList.length == 0) return;
    List<int> ids = [];
    String name =
        currentSelectList.map((e) => e.name).toSet().toList().join(', ');

    String payslipNumber =
        currentSelectList.map((e) => e.number).toSet().toList().join(', ');

    double total = 0.0;
    currentSelectList.forEach((element) {
      total += element.nettAmount;
      ids.add(element.id);
    });

    CustomExpenseData customData = CustomExpenseData(
      ids: ids,
      orderType: 'payslip',
      number: payslipNumber,
      paidTo: name,
      totalAmount: total,
    );
    Map<String, dynamic> result =
        await Routes.navigateTo(RouterGenProviders.newCashOutPage, params: {
      'customExpenseData': customData,
    });

    if (result != null) {
      DateTime paidAt = DateTime.now();
      Providers.get<HrAndPayrollProvider>(
              RouterGenProviders.hrAndPayrollPage, null)
          ?.getChildProvider<PayrollProvider>()
          ?.batchUpdatePayslipStatus(
              currentSelectList.map((e) => e.id).toList(),
              'closed',
              paidAt,
              result['payment_method']);
      if (!Config.hasPermission(PermissionUtils.homeDashboard))
        Config.dashboardProvider
            ?.getChildProvider<HrAndPayrollProvider>()
            ?.getChildProvider<PayrollProvider>()
            ?.batchUpdatePayslipStatus(
                currentSelectList.map((e) => e.id).toList(),
                'closed',
                paidAt,
                result['payment_method']);
      currentSelectList.clear();
      obtainContext?.call((context) async {
        Navigator.of(context).pop();
        Providers.get<HrAndPayrollProvider>(
                RouterGenProviders.hrAndPayrollPage, null)
            ?.getChildProvider<EmployeeProvider>()
            ?.refreshController
            ?.requestRefresh();
        if (!Config.hasPermission(PermissionUtils.homeDashboard))
          Config.dashboardProvider
              ?.getChildProvider<HrAndPayrollProvider>()
              ?.getChildProvider<EmployeeProvider>()
              ?.refreshController
              ?.requestRefresh();
      });
    }
  }

  void onCancel() {
    obtainContext?.call((context) {
      Navigator.of(context).pop();
    });
  }

  void onSelect(PayslipsItemEntity item1) {
    if (currentSelectList.contains(item1)) {
      currentSelectList.remove(item1);
    } else {
      currentSelectList.add(item1);
    }
    update();
  }

  @override
  FutureOr<List<PayslipsItemEntity>> transformData(
      List<PayslipsItemEntity> d, bool isCache) {
    groupMap.clear();
    contactToMap(d);
    return super.transformData(d, isCache);
  }

  void onDeselectAll() {
    currentSelectList.clear();
    update();
  }

  void onSelectAll() {
    currentSelectList.addAll(List.from(data));
    update();
  }

  @override
  void searchRefreshData(searchData) {
    transformData(data, false);
    update();
  }

  void contactToMap(List<PayslipsItemEntity> list) {
    sortGroupToMap(list,
        sort: (a, b) => sortIssuesAt(a, b, (t) => t.startDate, (t) => t.id),
        filter: (a) =>
            onFilterSearch(searchController.text, a.name) ||
            onFilterSearch(searchController.text, a.number),
        group: (a) => groupMonth(a, (t) => t.startDate));
  }
}
